package com.protocol;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.message.Message;
import com.message.factory.MessageDeSerializerAbstractFactory;
import com.message.factory.MessageDeSerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;

import java.util.List;

/**
 * 必须和 LengthFieldBasedFrameDecoder 一起使用，在 LengthFieldBasedFrameDecoder 之后再使用本 Codec
 * 才能保证解析出一条完成的消息
 */
@ChannelHandler.Sharable
public class SharedMessageCodec extends MessageToMessageCodec<ByteBuf, Message> {

    private final MessageDeSerializerAbstractFactory messageDeSerializerAbstractFactory;

    public SharedMessageCodec( MessageDeSerializerAbstractFactory messageDeSerializerAbstractFactory) {

        this.messageDeSerializerAbstractFactory = messageDeSerializerAbstractFactory;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {

        ByteBuf out = ctx.alloc().buffer();

//        new WebSocketServerCompressionHandler();
//      1、协议的魔数 （4个字节）

        out.writeBytes(MessageCodec.Magic_Number);
//      2、协议的版本号
        out.writeByte(1);
//      3、协议的序列化算法。0:json、1:jdk
        out.writeByte(0);
//      4、协议的类型
        out.writeByte(msg.getMessageType());
//      5、请求序号  （4个字节）
        out.writeInt(msg.getSequenceId());
//      6、内容长度   （4个字节）
        byte[] bytes = new ObjectMapper().writeValueAsBytes(msg);
        out.writeInt(bytes.length);
//      7、具体消息内容
        out.writeBytes(bytes);

//TODO      注意，这里与 MessageCodec 有一点不同
        outList.add(out);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

//      1、协议的魔数 （4个字节）
        ByteBuf byteBuf = in.readBytes(4);

        for (int i = 0; i < MessageCodec.Magic_Number.length; i++) {
            if (byteBuf.getByte(i) != MessageCodec.Magic_Number[i]) {
                throw new IllegalArgumentException("该协议不符合");
            }
        }
//      2、协议的版本号
        byte version = in.readByte();

        //      3、协议的序列化算法。0:json、1:jdk
        byte SerializationAlgorithm = in.readByte();

//      4、协议的类型
        byte messageType = in.readByte();
//      5、请求序号  （4个字节）
        ByteBuf sequenceId = in.readBytes(4);
//      6、内容长度   （4个字节）
        int length = in.readInt();

        byte[] content = new byte[length];
//      7、具体消息内容
        in.readBytes(content);



        Message message = messageDeSerializerAbstractFactory.readMessage(content, messageType);

//      Rpc 调用时特别指定的，为了标记谁的响应对应谁的请求
        message.setSequenceId(sequenceId.readInt());

//        LoginReqTo message = objectMapper.readValue(new String(content, StandardCharsets.UTF_8), LoginReqTo.class);


        out.add(message);
    }
}
